package com.ruoyi.course.controller;


import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.course.UtilMCTSCourseScheduling.DataAccessor;
import com.ruoyi.course.UtilMCTSCourseScheduling.MCTSkernel;
import com.ruoyi.course.UtilMCTSCourseScheduling.DataPreprocessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * MCTS排课控制器
 */
@RestController
@RequestMapping("/course/mcts")
public class UtilMCTSCourseSchedulingcontroller {

    private static final Logger logger = LoggerFactory.getLogger(UtilMCTSCourseSchedulingcontroller.class);

    @Autowired
    private DataPreprocessor dataPreprocessor;

    @Autowired
    private DataAccessor dataAccessor;

    /**
     * 执行MCTS排课算法
     */
    @GetMapping("/schedule")
    public AjaxResult scheduleCourses(
            @RequestParam(required = true) int semesterId,    // 学期ID（必填）
            @RequestParam(required = true) int academicYear,  // 学年（必填）
            // 以下参数暂不使用，仅为保持接口兼容性
            @RequestParam(required = true) boolean runFullMCTS,
            @RequestParam(required = true) int iterations,
            @RequestParam(required = false, defaultValue = "600000") long timeoutMillis,
            @RequestParam(required = false, defaultValue = "2000") int earlyStopThreshold,
            @RequestParam(required = false, defaultValue = "0.01") double scoreImprovementThreshold,
            @RequestParam(required = false, defaultValue = "0.6") double teacherWeight,
            @RequestParam(required = false, defaultValue = "0.4") double classroomWeight) {

        try {
            // 1.1 基础数据加载：核心预处理步骤
            // 作用：从数据源加载当前学期/学年的所有排课相关基础数据
            // 包括：课程班、教师信息、教室信息、时间槽、约束规则等
            logger.info("===== 开始数据预处理 =====");
            logger.info("1.1 加载学期[{}]、学年[{}]的基础排课数据...", semesterId, academicYear);
            DataPreprocessor.SchedulingData schedulingData = dataPreprocessor.processSchedulingData(semesterId, academicYear);

            // 1.2 数据加载结果验证
            // 作用：检查加载的数据是否完整、有效，是否存在阻断性错误
            logger.info("1.2 验证数据完整性和有效性...");
            Map<String, Object> preprocessResult = new HashMap<>();

            // 1.3 封装基础数据统计信息（用于查看预处理结果）
            preprocessResult.put("semesterId", semesterId);
            preprocessResult.put("academicYear", academicYear);
            preprocessResult.put("courseClassCount", schedulingData.getCourseClasses().size());  // 课程班数量
            preprocessResult.put("teacherCount", schedulingData.getTeachers().size());          // 教师数量
            preprocessResult.put("classroomCount", schedulingData.getClassroomOccupancy().size());  // 教室数量
            preprocessResult.put("timeSlotCount", schedulingData.getAllAvailableTimeSlots().size());        // 可用时间槽数量
            preprocessResult.put("hasCriticalErrors", schedulingData.hasCriticalErrors());      // 是否有严重错误

            // 1.4 若存在错误，添加错误详情
            if (schedulingData.hasCriticalErrors()) {
                preprocessResult.put("errors", schedulingData.getValidationErrors());
                logger.error("数据预处理失败，存在严重错误: {}", schedulingData.getValidationErrors());
            } else {
                logger.info("数据预处理完成，无严重错误");
                logger.info("统计信息：课程班[{}]个，教师[{}]个，教室[{}]个，时间槽[{}]个",
                        schedulingData.getCourseClasses().size(),
                        schedulingData.getTeachers().size(),
                        schedulingData.getClassroomOccupancy().size(),
                        schedulingData.getAllAvailableTimeSlots().size());
            }

            logger.info("===== 数据预处理阶段结束 =====");

            // 返回预处理结果（暂不执行后续MCTS流程）
            return AjaxResult.success("数据预处理完成", preprocessResult);

        } catch (Exception e) {
            logger.error("数据预处理过程发生异常", e);
            return AjaxResult.error("数据预处理失败: " + e.getMessage());
        }

        // 以下为后续MCTS排课流程代码，目前全部禁用
        /*
        // 1.2 构建初始状态（暂不执行）
        logger.info("1.2 开始构建初始状态...");
        DataPreprocessor.SchedulingConstraints constraints = dataPreprocessor.getSchedulingConstraints();
        final MctsState initialState = new MctsState(schedulingData, constraints, dataAccessor);

        // 1.3 参数配置（暂不执行）
        logger.info("1.3 开始参数配置...");
        initialState.setTerminationParameters(iterations, timeoutMillis, earlyStopThreshold, scoreImprovementThreshold);
        initialState.setScoreWeights(teacherWeight, classroomWeight);
        initialState.setEvaluationBaseParameters(60, 20, 20);

        // 初始化MCTS核心（暂不执行）
        MCTSkernel mctsKernel = new MCTSkernel(initialState, dataAccessor);

        // 后续2.0及以后的MCTS流程均暂不执行...
        */
    }


//        // 1.2 构建初始状态
//        try {
//            logger.info("1.2 开始构建初始状态...");
//            DataPreprocessor.SchedulingConstraints constraints = dataPreprocessor.getSchedulingConstraints();
//            final MctsState initialState = new MctsState(schedulingData, constraints, dataAccessor);
//
//            // 1.3 参数配置
//            logger.info("1.3 开始参数配置...");
//            initialState.setTerminationParameters(iterations, timeoutMillis, earlyStopThreshold, scoreImprovementThreshold);
//            initialState.setScoreWeights(teacherWeight, classroomWeight);
//            initialState.setEvaluationBaseParameters(60, 20, 20);
//
//            // 初始化MCTS核心
//            MCTSkernel mctsKernel = new MCTSkernel(initialState, dataAccessor);

//            // 如果需要执行完整MCTS流程
//            if (runFullMCTS) {
//                logger.info("开始执行完整MCTS排课流程...");
//                mctsKernel.runMCTS();
//
//                // 获取最佳排课方案
//                Map<String, List<com.ruoyi.course.UtilMCTSCourseScheduling.DataPreprocessor.TimeSlot>> bestSchedule =
//                        mctsKernel.getBestSchedule();
//
//                // 构建结果
//                Map<String, Object> result = new HashMap<>();
//                result.put("bestScore", mctsKernel.findBestScore());
//                result.put("scheduledCoursesCount", bestSchedule.size());
//                result.put("remainingCoursesCount", initialState.getRemainingCourseCount() - bestSchedule.size());
//                result.put("scheduleDetails", bestSchedule);
//
//                return AjaxResult.success("MCTS排课完成", result);
//            } else {
//                // 执行单步MCTS流程（选择->扩展->模拟->回溯）
//                logger.info("执行单步MCTS流程...");
//
//                // 2.1 选择阶段
//                logger.info("2.1 开始执行MCTS选择阶段...");
//                final MCTSkernel.TreeNode selectedNode = mctsKernel.selectPromisingNode();
//
//                if (selectedNode == null) {
//                    logger.error("2.1 选择阶段未找到有效节点");
//                    return AjaxResult.error("MCTS选择阶段失败：未找到有效节点");
//                }
//
//                // 2.2 扩展阶段
//                logger.info("2.2 开始执行MCTS扩展阶段...");
//                mctsKernel.expandNode(selectedNode);
//
//                final int childCount = selectedNode.getChildren().size();
//                logger.info("2.2 扩展阶段完成，生成子节点数量: {}", childCount);
//
//                // 2.3 模拟阶段
//                logger.info("2.3 开始执行MCTS模拟阶段...");
//                double totalScore = 0;
//                int simulatedCount = 0;
//
//                if (!selectedNode.getChildren().isEmpty()) {
//                    for (MCTSkernel.TreeNode child : selectedNode.getChildren()) {
//                        double score = mctsKernel.simulate(child);
//                        totalScore += score;
//                        simulatedCount++;
//                    }
//                }
//
//                final double avgScore = simulatedCount > 0 ? totalScore / simulatedCount : 0;
//                // 创建simulatedCount的final副本，供内部类使用
//                final int finalSimulatedCount = simulatedCount;
//                logger.info("2.3 模拟阶段完成，平均得分: {:.2f}", avgScore);
//
//                // 2.4 回溯阶段
//                logger.info("2.4 开始执行MCTS回溯阶段...");
//                if (!selectedNode.getChildren().isEmpty()) {
//                    // 选择最佳子节点进行回溯
//                    final MCTSkernel.TreeNode bestChild = selectedNode.getChildren().stream()
//                            .max(Comparator.comparingDouble(node ->
//                                    node.getVisitCount() == 0 ? 0 : node.getTotalScore() / node.getVisitCount()))
//                            .orElse(null);
//
//                    if (bestChild != null) {
//                        mctsKernel.backpropagate(bestChild, bestChild.getTotalScore() / bestChild.getVisitCount());
//                    }
//                }
//
//                // 构建返回结果
//                Map<String, Object> resultMap = new HashMap<>();
//                resultMap.put("initialState", new HashMap<String, Object>() {{
//                    put("remainingCourses", initialState.getRemainingCourseCount());
//                    put("totalTimeSlots", initialState.getAllAvailableTimeSlots().size());
//                }});
//                resultMap.put("selectionResult", new HashMap<String, Object>() {{
//                    put("remainingCourses", selectedNode.getState().getRemainingCourseCount());
//                    put("isLeafNode", selectedNode.isLeafNode());
//                }});
//                resultMap.put("expansionResult", new HashMap<String, Object>() {{
//                    put("childNodeCount", childCount);
//                    put("fullyExpanded", selectedNode.isFullyExpanded());
//                }});
//                resultMap.put("simulationResult", new HashMap<String, Object>() {{
//                    // 使用final副本变量
//                    put("simulatedNodes", finalSimulatedCount);
//                    put("averageScore", avgScore);
//                }});
//
                //return AjaxResult.success("MCTS单步流程执行完成", resultMap);
//            }

//        } catch (Exception e) {
//            logger.error("排课处理流程失败", e);
//            return AjaxResult.error("处理失败: " + e.getMessage());
//        }
//    }


//        2.3 模拟是基于当前节点状态快速模拟剩余课程排课并评估节点评分的过程。
//        2.4 回溯是将模拟评分反向传播，更新路径上节点的访问次数和累计评分的步骤。
//
//        3.0 终止与结果处理阶段是满足终止条件后，筛选最优排课方案并执行最终处理的过程。
//        3.1 选择最优状态是从根节点子节点中选取评分最高的节点作为最优排课方案的操作。
//        3.2 执行最终排课动作是对最优状态的课程执行排课，并更新学生时间槽Map的过程。
//        3.3 输出与收尾是打印最终排课统计信息并释放临时资源的操作。


}
